//
// Created by Jisam on  23/10/2024 22:08.
// Solution of  P1868 饥饿的奶牛
// 2024-10-23 22:54:13 AC 100 动态规划
#include <bits/stdc++.h>

#define int long long
#define endl "\n"
#define all(x) (x).begin(), (x).end()
#define pb push_back
using namespace std;
int f[(int)1e7 + 5];
// 主函数
signed main()
{
    // 关闭输入输出流同步，加快输入输出速度
    cin.tie(nullptr)->sync_with_stdio(false);
    int n;
    cin >> n;
    // 存储每个时间段的开始和结束时间
    vector<pair<int, int>> a(n);
    int _max = 0;
    // 输入每个时间段的开始和结束时间，并记录最晚的结束时间
    for (int i = 0; i < n; i++)
    {
        cin >> a[i].first >> a[i].second;
        _max = max(_max, a[i].second);
    }
    // 按照开始时间升序排序，如果开始时间相同，则按照结束时间升序排序
    sort(all(a), [&](pair<int, int> a, pair<int, int> b) -> bool
         { return a.first == b.first? a.second < b.second : a.first < b.first; });
    // 输出排序后的时间段信息，用于调试
    for (int i = 0; i < n; i++)
        cerr << a[i].first << " " << a[i].second << endl;
    int j = 0;
    int ans = 0;
    // 遍历从0到最晚结束时间的每个时间点
    for (int i = 0; i <= _max; i++)
    {
        // 更新当前时间点的最大吃草量，取前一个时间点的最大吃草量和当前时间点的最大吃草量的较大值
        f[i] = max(f[i], f[i - 1]);
        // 当当前时间点等于某个时间段的开始时间时
        while (a[j].first == i && j < n)
        {
            // 更新该时间段结束时间的最大吃草量，取前一个时间点的最大吃草量和当前时间段开始时间的最大吃草量加上当前时间段吃草量的较大值
            f[a[j].second] = max(f[a[j].second], f[a[j].first - 1] + a[j].second - a[j].first + 1);
            // 移动到下一个时间段
            j++;
        }
        // 更新答案，取当前时间点的最大吃草量和当前答案的较大值
        ans = max(ans, f[i]);
    }
    // 输出最大吃草量
    cout << ans << endl;
    return 0;
}
